package com.example.demo.stream;

import com.example.demo.model.Author;
import com.example.demo.model.Book;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 马拉圈
 * Date: 2023-11-21
 * Time: 11:08
 */
public class StreamDemo {

    public static void main1(String[] args) {
//        System.out.println(Author.getAuthors());
        List<Author> list = Author.getAuthors(); // 获取集合
        Set<Author> set = new HashSet(list);
        list.stream()// 获取集合的流对象
                .distinct() // 去重
                .filter(x -> x.getAge().compareTo(18) < 0) // 过滤
                .forEach(x -> System.out.println(x)) // 终结操作
        ;
        set.stream()// 获取集合的流对象
                .distinct() // 去重
                .filter(x -> x.getAge().compareTo(18) < 0) // 过滤
                .forEach(x -> System.out.println(x)) // 终结操作
        ;
    }

    public static void main2(String[] args) {
        Integer[] arr = {1, 2, 3, 4, 5};
        Arrays.stream(arr)
                .distinct()
                .filter(x -> x > 2)
                .forEach(x -> System.out.println(x))
        ;
        Stream.of(arr)
                .distinct()
                .filter(x -> x > 2)
                .forEach(x -> System.out.println(x))
        ;
    }

    public static void main3(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>(){{
            this.put("555", 5);
            this.put("666", 6);
            this.put("777", 7);
            this.put("888", 8);
            this.put("999", 9);
        }};

        map.entrySet().stream()
                .distinct()
                .filter(x -> x.getValue() > 7)
                .forEach(x -> System.out.println(x))
        ;
    }

    public static void main4(String[] args) {
        List<Author> list = Author.getAuthors();
        list.stream()
                .filter(author -> author.getName() != null && author.getName().length() > 1)
                .forEach(author -> System.out.println(author));
        ;
        System.out.println("---------------------------------------------------------------------------");
        list.stream()
                .map(author -> author.getName())
                .distinct()
                .forEach(s -> System.out.println(s));
        ;
        System.out.println("---------------------------------------------------------------------------");
        list.stream()
                .map(author -> author.getAge() + 1)
                .map(age -> String.valueOf(age + 10))
                .map(s -> s + s + s)
                .distinct()
                .forEach(s -> System.out.println(s));
        ;
        System.out.println("---------------------------------------------------------------------------");
        list.stream()
                .distinct()
                .sorted((o1, o2) -> o2.getAge().compareTo(o1.getAge()))
                .forEach(x -> System.out.println(x.getAge()))
        ;
        System.out.println("---------------------------------------------------------------------------");
        list.stream()
                .distinct()
                .sorted((o1, o2) -> o2.getAge().compareTo(o1.getAge()))
                .map(author -> author.getName())
                .limit(2)
                .forEach(x -> System.out.println(x))
        ;
        System.out.println("---------------------------------------------------------------------------");
        list.stream()
                .distinct()
                .sorted((o1, o2) -> o2.getAge().compareTo(o1.getAge()))
                .skip(1)
                .forEach(x -> System.out.println(x))
        ;
        System.out.println("---------------------------------------------------------------------------");
        list.stream()
                .flatMap(author -> author.getBooks().stream())
                .distinct()
                .forEach(x -> System.out.println(x.getName()));
        ;
        System.out.println("---------------------------------------------------------------------------");
        list.stream()
                .flatMap(author -> author.getBooks().stream())
//                .map(book -> book.getCategory())
                .flatMap(book -> Arrays.stream(book.getCategory().split(",")))
                .distinct()
                .filter(s -> !s.equals("哲学"))
                .filter(s -> !s.equals("爱情"))
                .forEach(s -> System.out.println(s))
        ;
    }

    public static void main5(String[] args) {
        List<Author> list = Author.getAuthors();
        long count = list.stream()
                .flatMap(author -> author.getBooks().stream())
                .distinct()
                .count()
        ;
        System.out.println(count);
        System.out.println("---------------------------------------------------------------------------");
        Optional<Book> max = list.stream()
                .flatMap(author -> author.getBooks().stream())
                .max(((o1, o2) -> o1.getScore().compareTo(o2.getScore())));
        System.out.println(max.get());
        Optional<Book> min = list.stream()
                .flatMap(author -> author.getBooks().stream())
                .min(((o1, o2) -> o1.getScore().compareTo(o2.getScore())));
        System.out.println(min.get());
        System.out.println("---------------------------------------------------------------------------");
        List<Book> books = list.stream()
                .flatMap(author -> author.getBooks().stream())
                .distinct()
                .collect(Collectors.toList());
        System.out.println(books);
        Set<Book> bookSet = list.stream()
                .flatMap(author -> author.getBooks().stream())
                .collect(Collectors.toSet());
        System.out.println(bookSet);
        Map<String, List<Book>> collect = list.stream()
                .distinct()
                .collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
        System.out.println(collect);

    }

    public static void main6(String[] args) {
        List<Author> list = Author.getAuthors();
        boolean flag = list.stream()
                .anyMatch(author -> author.getAge().compareTo(29) > 0);
        System.out.println(flag);
        flag = list.stream()
                .allMatch(author -> author.getAge().compareTo(29) > 0);
        System.out.println(flag);
        flag = list.stream()
                .noneMatch(author -> author.getAge().compareTo(100) > 0);
        System.out.println(flag);
    }

    public static void main7(String[] args) {
        List<Author> list = Author.getAuthors();
        list.stream()
                .filter(author -> author.getAge().compareTo(188) > 0)
                .findAny()
                .ifPresent(author -> System.out.println(author));

        list.stream()
                .sorted((o1, o2) -> o1.getAge().compareTo(o2.getAge()))
                .findFirst()
                .ifPresent(author -> System.out.println(author));

        List<Author> list1 = new ArrayList<>(Author.getAuthors());
//        list1.add(null);
        Object[] objects = list1.toArray();
        if(!Arrays.stream(objects).allMatch(o -> o != null)) {
            System.out.println("isnull");
        }
    }

    public static void main8(String[] args) {
        List<Author> list = Author.getAuthors();
        String name = "";
        Integer reduce1 = list.stream()
                .map(author -> author.getAge())
                .reduce(0, (x1, x2) -> x1 += x2);
        System.out.println(reduce1);
        List<Book> list1 = new ArrayList();
        String reduce2 = list.stream()
                .map(author -> author.getName())
                .reduce(name, (x1, x2) -> x1 += x2);
        System.out.println(name);
        System.out.println(reduce2);

        List<Book> reduce3 = list.stream()
                .map(author -> author.getBooks())
                .reduce(list1, (x1, x2) -> {
                    list1.addAll(x2);
                    return list1;
                });
        System.out.println(reduce3);
        System.out.println(list1);
        System.out.println(reduce3 == list1);

        Integer reduce4 = list.stream()
                .map(author -> author.getAge())
                .reduce(0, (x1, x2) -> Math.max(x1, x2));

        Integer reduce5 = list.stream()
                .map(author -> author.getAge())
                .reduce(Integer.MAX_VALUE, (x1, x2) -> Math.min(x1, x2));
        System.out.println(reduce4);
        System.out.println(reduce5);

    }

    public static void main9(String[] args) {
        List<Author> list = Author.getAuthors();
        list.stream()
                .map(author -> author.getBooks())
                .reduce((x1, x2) -> {
                    x1.addAll(x2);
                    return x1;
                })
                .ifPresent(books -> System.out.println(books))
        ;
        list.stream()
                .map(author -> author.getBooks())
                .reduce((x1, x2) -> {
                    x1.addAll(x2);
                    return x1;
                })
                .ifPresent(books -> System.out.println(books))
        ;
    }

    public static void main10(String[] args) {
        List<Author> authors = Author.getAuthors();
        authors.stream()
                .distinct()
                .filter(((Predicate<Author>) author -> author.getAge().compareTo(17) > 0)
                        .and(author -> Optional.ofNullable(author).orElseThrow(() -> new RuntimeException("没有名字")).getName().length() > 1))
                .forEach(author -> System.out.println(author));
        ;
    }



    public static void main11(String[] args) {
        List<Author> list = Author.getAuthors();
        List<String> authors = Author.getAuthors().stream().map(author -> author.getName()).collect(Collectors.toList());
        list.stream()
                .map(author -> author.getName())
                .map(name -> String.valueOf(name))
                .forEach(s -> System.out.println(s));
        ;
        list.stream()
                .map(author -> author.getName())
                .map(String::valueOf)
                .forEach(s -> System.out.println(s));
        ;
        list.stream()
                .map(author -> author.getName())
                .forEach(name -> authors.add(name));
        ;
        list.stream()
                .map(author -> author.getName())
                .forEach(authors::add);
        ;
        list.stream()
                .map(author -> author.getName())
                .map(String::valueOf)
                .forEach(System.out::println);
        ;

        list.stream()
                .map(Author::getName)
                .forEach(authors::add);
        ;

        list.stream()
                .distinct()
                .map(Author::getName)
                .map(name -> subAuthorName(name, 0, 1, String::substring))
                .forEach(System.out::println);
        ;
        list.stream()
                .distinct()
                .map(Author::getName)
                .map(name -> new StringBuilder(name))
                .forEach(System.out::println);
        ;
        list.stream()
                .distinct()
                .map(Author::getName)
                .map(StringBuilder::new)
                .forEach(System.out::println);
        ;
    }

    public static String subAuthorName(String str, int start, int length, UseString useString) {
        return useString.use(str, start, length);
    }


    public static void main12(String[] args) {
        List<Author> list = Author.getAuthors();
        list.stream()
                .distinct()
                .mapToInt(Author::getAge)
                .map(age -> age + 10)
                .filter(age -> age > 18)
                .map(age -> age + 2)
                .forEach(System.out::println);
        ;
        list.stream()
                .distinct()
                .map(Author::getAge)
                .map(age -> age + 10)
                .filter(age -> age > 18)
                .map(age -> age + 2)
                .forEach(System.out::println);
        ;
    }

    public static void main13(String[] args) {
        Stream.of(1, 2, 3, 4, 5)
                .mapToInt(x -> x)
                .filter(x -> x > 1)
                .reduce((x1, x2) -> x1 += x2)
                .ifPresent(System.out::println);
        ;
        Stream.of(1, 2, 3, 4, 5).parallel()
                .mapToInt(x -> x)
                .filter(x -> x > 1)
                .reduce((x1, x2) -> x1 += x2)
                .ifPresent(System.out::println);
        ;

    }

    public static void main14(String[] args) {
        Stream.of(1, 2, 3, 4, 5).parallel()
                .peek(System.out::println)
                .mapToInt(x -> x)
                .filter(x -> x > 1)
                .reduce((x1, x2) -> x1 += x2)
                .ifPresent(System.out::println);
        ;

        Stream.of(1, 2, 3, 4, 5).parallel()
                .peek(x -> System.out.println(x + "   " + Thread.currentThread().getName()))
                // 区别于foreach，这个可以在中偷看调试流对象，而其他终结操作是返回值的，没有对应的peek这种的消费数据的方法
                // 并且，这个不算终结方法，所以整体没有终结方法的话，这个peek也不会生效
                .mapToInt(x -> x)
                .filter(x -> x > 1)
                .reduce((x1, x2) -> x1 += x2)
                .ifPresent(System.out::println);
        ;
        Stream.of(1, 2, 3, 4, 5).parallel()
                .forEach(System.out::println);
        ;
    }

    public static void main(String[] args) {
        List<Author> list = Author.getAuthors();
        Integer reduce1 = list.stream().parallel()
                .map(Author::getAge)
                .reduce(0, (x1, x2) -> x1 += x2);
        System.out.println(reduce1);

        Integer reduce2 = list.parallelStream()
                .map(Author::getAge)
                .reduce(0, (x1, x2) -> x1 += x2);
        System.out.println(reduce2);
    }



 }
